package com.mebs.model.inventory;

import static org.hibernate.proxy.HibernateProxyHelper.getClassWithoutInitializingProxy;

import com.mebs.model.AttachedFile;
import com.mebs.model.Vendor;
import com.mebs.model.Warehouse;
import com.mebs.model.attachments.AttachableObject;

import javax.persistence.*;
import java.util.Set;
import java.util.Collection;
import java.util.ArrayList;

import org.jt.jet.util.JetUtils;

/**
 * Created by Sergey Prasolov, sap@jensentechnologies.com Date: Feb 20, 2006,
 * 2:22:54 PM
 */
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "PO_ORDER")
@PrimaryKeyJoinColumn(name = "Id")
public class PurchaseOrder extends AbstractOrder implements AttachableObject{
	@ManyToOne(optional = false)
	@JoinColumn(name = "VendorId")
	private Vendor vendor;

	@Column(name = "Number", nullable = false, length = 250)
	private String number;

	@ManyToMany(targetEntity = com.mebs.model.inventory.Won.class)
	private Set wons;

	@Column(name = "Priority", nullable = true)
	private Integer priority;

/*
	@ManyToOne(optional = true)
	@JoinColumn(name = "WarehouseId")
	private Warehouse warehouse;
*/

	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinColumn(name = "OrderId")
	@OrderBy("lineNumber")
	private Set<OrderItem> items;

	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinColumn(name = "OrderId")
	@OrderBy("sequence")
	private Set<Confirmation> confirmations;

        @ManyToOne(optional = true)
        @JoinColumn(name = "FileId")
        private AttachedFile file;

	@Transient
	private Integer mNumber;

	/**
	 * ********************** Getters-setters ***********************
	 */
	public Vendor getVendor() {
		return vendor;
	}

	public void setVendor(Vendor vendor) {
		this.vendor = vendor;
	}

/*
	public Warehouse getWarehouse() {
		return warehouse;
	}

	public void setWarehouse(Warehouse warehouse) {
		this.warehouse = warehouse;
	}
*/

	public Set<OrderItem> getItems() {
		return items;
	}

	public void setItems(Set<OrderItem> items) {
		this.items = items;
	}

	public Set<Confirmation> getConfirmations() {
		return confirmations;
	}

	public void setConfirmations(Set<Confirmation> confirmations) {
		this.confirmations = confirmations;
	}

	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	public Set getWon() {
		return wons;
	}

	public void setWon(Set wons) {
		this.wons = wons;
	}

	public Integer getPriority() {
		return priority;
	}

	public void setPriority(Integer priority) {
		this.priority = priority;
	}

	@Override
	public String toString() {
		return this.number;
	}

	@Transient
	public Collection<OrderItem> getAvailableItems() {
		ArrayList<OrderItem> orderItems = new ArrayList<OrderItem>();
		for (OrderItem nextItem : this.items) {
			orderItems.add(nextItem);
		}
		return orderItems;
	}

	@Transient
	public String getSequenceNumber() {
		return this.number;
	}

	@Transient
	public int getNextLineNumber() {
		int nextLineNumber = 1;
		if (!JetUtils.isEmpty(items)) {
			for (OrderItem oi : items) {
				if (oi.getLineNumber() >= nextLineNumber)
					nextLineNumber = oi.getLineNumber() + 1;
			}
		}
		return nextLineNumber;
	}

	@Transient
	public boolean isDeletable() {
		return JetUtils.isEmpty(this.items)
				&& JetUtils.isEmpty(this.confirmations);
	}

	@Transient
	public int getTotal() {
		int total = 0;
		if (getItems() != null) {
			for (OrderItem item : getItems()) {
				total += item.getTotalPrice() == null ? 0: item.getTotalPrice();
			}
		}
		return total;
	}

	@Transient
	public int getTotalOverShort() {
		int total = 0;
		if (getItems() != null) {
			for (OrderItem item : getItems()) {
                            if(item.getOverShort() < 0)
				total += item.getOverShort();
			}
		}
		return total;
	}
	
	@Transient
	public int getTotalReceived() {
		int total = 0;
		if (getItems() != null) {
			for (OrderItem item : getItems()) {
				total += item.getReceivedQuantity();
			}
		}
		return total;
	}

    public AttachedFile getFile() {
        return file;
    }

    public void setFile(AttachedFile file) {
        this.file = file;
    }
    
    @Override
    public int hashCode() {
        if (number == null) return super.hashCode();
        return number.hashCode();
    }
    
    @Override
    public boolean equals(Object o) {
    	if (o == null || !(o instanceof PurchaseOrder)) return false;
        if (this == o) return true;
        if (number == null) return false;
        
        final PurchaseOrder that = (PurchaseOrder) o;
        return number.equals(that.getNumber());
    }
}
